import { Flex, Input, Spin, Tree, TreeDataNode } from 'antd';
import React, { useEffect, useRef, useState } from 'react';

import { batteryControllerGetDeviceTreeDatas } from '@/services/ess/deviceBattery';
import { formatterTree } from '@/utils/formatterTree';
import { useModel } from '@@/exports';
import { SearchOutlined } from '@ant-design/icons';

const RUN_STATE: Record<string | number, { label: string; value: string }> = {
  0: {
    label: '静置',
    value: 'stop',
  },
  1: {
    label: '充电',
    value: 'charge',
  },
  2: {
    label: '放电',
    value: 'discharge',
  },
};

const ONLINE_STATE: Record<string | number, { label: string; value: string }> = {
  0: {
    label: '离线',
    value: 'offline',
  },
  1: {
    label: '在线',
    value: 'online',
  },
};

const HistoryData: React.FC = () => {
  const treeRef = useRef(null);
  const { initialState } = useModel('@@initialState');
  const [spinning, setSpining] = useState(false);
  const [dataList, setDataList] = useState();
  const [treeData, setTreeData] = useState<TreeDataNode[]>([]);
  const [selectedNode, setSelectedNode] = useState();
  const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
  // const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
  const [autoExpandParent, setAutoExpandParent] = useState(true);

  const handleSelectTreeNode = (selectedKeys: number, e) => {
    setSelectedNode(e.node);
    // setAutoExpandParent(false);
  };

  const onExpand = (expandedKeys: React.Key[]) => {
    setExpandedKeys(expandedKeys);
    setAutoExpandParent(false);
  };

  /**
   * 获得第一组展开树的ID
   * @param tree
   */
  const getFirstExpandId = (tree: any) => {
    const idArray: string[] | number[] = [];

    function getId(arr: any) {
      idArray.push(arr[0]?.id);
      if (arr[0].children.length > 0) {
        getId(arr[0].children);
      }
    }

    getId(tree);
    return idArray;
  };

  const getParentKey = (key: React.Key, tree: TreeDataNode[]): React.Key => {
    let parentKey: React.Key;
    for (let i = 0; i < tree.length; i++) {
      const node = tree[i];
      if (node.children) {
        if (node.children.some((item) => item.id === key)) {
          parentKey = node.id;
        } else if (getParentKey(key, node.children)) {
          parentKey = getParentKey(key, node.children);
        }
      }
    }
    return parentKey!;
  };

  useEffect(() => {
    setSpining(true);
    batteryControllerGetDeviceTreeDatas({ stationId: initialState?.stationId })
      .then((res) => {
        if (res.data) {
          const combined = [
            ...(res?.data?.deviceBmsInfos || []),
            ...(res?.data?.deviceBmuInfos || []),
            ...(res?.data?.deviceBoxInfos || []),
            ...(res?.data?.deviceClusterInfos || []),
            ...(res?.data?.deviceGlcInfos || []),
            ...(res.data?.deviceLcClusterInfos || []),
            ...(res?.data?.deviceLcInfos || []),
          ];
          setDataList(combined);
          setTreeData(formatterTree(combined));
          setExpandedKeys(getFirstExpandId(formatterTree(combined)));
          setSelectedNode(res?.data?.deviceBmuInfos[0]);
          setSpining(false);
        } else {
          setSpining(false);
        }
      })
      .catch(() => {
        setSpining(false);
      });
  }, []);

  const filterTree = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target;
    const newExpandedKeys = dataList
      .map((item) => {
        if (item.name.indexOf(value) > -1) {
          return getParentKey(item.id, treeData);
        }
        return null;
      })
      .filter((item, i, self): item is React.Key => item && self.indexOf(item) === i);
    setExpandedKeys(newExpandedKeys);
    setAutoExpandParent(true);
  };

  return (
    <Spin spinning={spinning}>
      <div style={{ background: '#fff', padding: '0 24px 30px 24px' }}>
        <Flex>
          <div
            style={{
              width: 300,
              minWidth: 300,
              paddingRight: 25,
              marginRight: 25,
              borderRight: '1px solid #e0e0e0',
              position: 'sticky',
              top: 68,
            }}
          >
            <Input
              style={{ marginBottom: 8 }}
              placeholder={'请输入'}
              addonAfter={<SearchOutlined />}
              onChange={(e) => {
                filterTree(e);
              }}
            ></Input>
            <Tree
              autoExpandParent={autoExpandParent}
              ref={treeRef}
              height={600}
              expandedKeys={expandedKeys}
              selectedKeys={[selectedNode?.id]}
              treeData={treeData}
              fieldNames={{
                title: 'name',
                key: 'id',
                children: 'children',
              }}
              titleRender={(treeDataNode) => {
                const node = treeDataNode as API.DeviceInfoDTO;
                const runState = RUN_STATE[node.runState as string];
                const onlineState = ONLINE_STATE[node.onlineState as number];
                return (
                  <div style={{ padding: '4px 0' }}>
                    <p style={{ margin: 0 }}>{node.name}</p>
                    <div
                      style={{
                        display: 'flex',
                        gap: 4,
                        alignItems: 'center',
                        flexWrap: 'wrap',
                      }}
                    >
                      {node.soc !== null && (
                        <p className="htn-badge htn-badge-soc">{`${node.soc}%`}</p>
                      )}
                      {node.runState !== null && runState && (
                        <p className={`htn-badge htn-badge-${runState.value}`}>{runState.label}</p>
                      )}
                      {node.onlineState !== null && onlineState && (
                        <p className={`htn-badge htn-badge-${onlineState.value}`}>
                          {onlineState.label}
                        </p>
                      )}
                      {!!node.faultCount && (
                        <p className="htn-badge htn-badge-fault">{`故障 ${
                          node.faultCount > 99 ? '99+' : node.faultCount
                        }`}</p>
                      )}
                    </div>
                  </div>
                );
              }}
              onSelect={handleSelectTreeNode}
              onExpand={onExpand}
            ></Tree>
          </div>

          <div style={{ width: 'calc(100% - 325px)' }}>信息</div>
        </Flex>
      </div>
    </Spin>
  );
};

export default HistoryData;
